#/usr/bin/env ruby

require 'minigems'
require 'cloudservers'
require 'terminal-table'
require 'colorize'

class Interface

    def initialize(username, apikey)
        @username = username
        @apikey = apikey
    end

    def connect
        #Assume use connection 
        @conn = CloudServers::Connection.new(:username => @username, :api_key => @apikey)
    end
    
    def get_servers
        @servers = @conn.servers
        return @servers
    end

    def get_server(server=nil)
        if server == nil
            rows = []
            for s in @servers 
                rows << [ "#{s[:id]}".green, "#{s[:name]}\n"]
            end
            table = Terminal::Table.new :title => "Server Selection", :headings => ["ID", "Name",], :rows => rows
            string = "Which server would you like to know more about?: "
            puts table
            puts string
            server_string = gets.chomp
            server = server_string
        end
        @active_server_record = @conn.get_server(server)
        return @active_server_record
    end

    def get_server_details
        @server_details = @conn.list_servers_detail
        return @server_details
    end
    
    def get_images
        @server_images = @conn.list_images
        return @server_images
    end

    def get_flavors
        @flavors = @conn.list_flavors
        return @flavors
    end

    def get_image(id=nil)
        if id == nil
            rows = []
            if ! @server_images
                self.get_images
            end
            for s in @server_images
                rows << [ "#{s[:id]}".green,  "#{s[:name]}]".blue]
            end
            table = Terminal::Table.new :title => "Image Selection", :headings => ["ID", "Name",], :rows => rows
            string = "Which image do you want to know more about?: "
            puts table
            puts string
            image_string = gets.chomp
            image = image_string
        end
        @active_image_record = @conn.get_image(image)
        return @active_image_record
    end

    def select_flavor
        if ! @flavors
            self.get_flavors
        end
        rows = []
        for f in @flavors
            rows << [ "#{f[:id]}", "#{f[:name]}"]
        end
        table = Terminal::Table.new :title => "Flavor Selection", :headings => ["ID", "Name"], :rows => rows
        string = "Which flavor would you like to select?: "
        puts table
        puts string
        flavorid = gets.chomp
        @active_flavor_record = @conn.get_flavor(flavorid)
        puts "Active flavor record set to: #{@active_flavor_record.name}"
    end
        
    def delete
        puts "Are you sure you want to delete: #{@active_server_record.name}? "
        input = gets.chomp
        if input == 'yes' or input == 'y'
            @active_server_record.delete!
            puts "Request Sent."
        else
            return    
        end
    end

    def resize(flavorid)
        print "Are you sure you want to resize: #{self.active_server_record.name}"
        input = gets.chomp
        if input == "yes" or input == "y"
            self.check_active_server_record
            @active_server_record.resize(flavorid)
        else
            return
        end
    end

    def rebuild
        self.check_active_server_record
        @active_server_record.rebuild
    end    
    
    def create_image(name)
        self.check_active_server_record
        @active_server_record.create_image(name)
    end
    
    def create_server
        print "What would you like to name this server?: "
        name = gets.chomp
        self.get_image
        self.select_flavor
        print "Are you sure you want to create this server?: "
        input = gets.chomp
        if input == "yes" or input == "y"
            new_server = @conn.create_server(:name => name, :imageId => @active_image_record.id, :flavorId => @active_flavor_record.id)
            print "#{new_server.name} is currently building"
        else
            puts "Aborting creation of new server!"
            return
        end
    end
        
    def populate_server_records
        for server in @servers
            server_obj = @conn.get_server(server[:id])
            server_obj.populate 
        end
    end

    def show_server_detail
        rows = Array.new
        sobj = @conn.get_server(@active_server_record.id)
        rows << [sobj.id, sobj.name, sobj.status, sobj.progress, sobj.hostId, sobj.flavorId]
        table = Terminal::Table.new :title => "#{@active_server_record.name}'s Details", :headings => ["ID", "Name", "Status", "Progress", "Host Id", "FlavorId"], :rows => rows
        puts table
    end


            
        
        

    def get_flavor(id=nil)
        if id == nil
            self.check_active_server_record
            f = @active_server_record.flavor
            return f.name
        else
            s = self.get_server(id)
            f = s.flavor
            return f.name
        end
            
    end

    def reboot
        self.check_active_server_record
        print "Do you really want to reboot #{active_server_record.name}?: "
        check = gets
        if check == "yes" or check == "y"
            @active_server_record.reboot
        else
            return false
        end
    end

    def reboot!
        self.check_active_server_record
        @active_server_record.reboot!
    end

    def check_active_server_record
        if ! @active_server_record
            self.get_server
        end
    end
    
end

class Client < Interface

    def initialize(username, apikey)
        @username = username
        @apikey = apikey
        self.connect
        puts "Connected to Rackspace Cloud Servers Api!"
        self.get_servers
        puts "Gathered servers for account: #{@username}"
        self.get_images
        puts "Gathered Images for all servers!"
        self.get_server_details
        puts "Gathered server details!  Ready!"
    end

    def list_servers
        rows = []
        @server_details.each do |s|
            rows << [ "#{s[:name]}", "#{s[:id]}", "#{s[:addresses][:public]}", "#{s[:status]}".green, self.get_flavor(id=s[:id])]
        end
        table = Terminal::Table.new :title => "Cloudservers", :headings => ["Name", "ID", "Public IP", "Status", "Flavor"], :rows => rows
        puts table
    end

    def refresh_servers
        self.get_servers
        puts "[ Server table updated ]".green
    end

    def list_images
        rows = []
        @server_images.each do |i|
            rows << [ "#{i[:id]}", "#{i[:name]}"]
        end
        table = Terminal::Table.new :title => "CS Images", :headings => ["ID", "Name"], :rows => rows
        puts table
    end

    def refresh_images
        self.get_images
        puts "[ Image table updated ]".green
    end

    def select_server_record
        self.get_server
        puts "Active server record set to: #{@active_server_record.name}"
    end

    def show_active_server_record
        puts "Active Server Record: #{@active_server_record.name}"
    end
    
    def help
        hs = ''
        print <<-hs
            The Cloud Servers Cli client comes stock with all the commands available by the Cloud servers
            api.

            Commands:
               list servers: Shows a list of the servers you have.
               list images:  Shows a list of images that are available for you to build from.
               refresh servers: Re-request the list of servers from the api and update the local cache.
               refresh images:  Re-request the list of images fron the api and update the local cache.
               create server:  Begin dialog to build a server.
               select server:  Select which server is actively being used by the cli.
               show active server:  Shows which server is active.
               exit: quit the client
        hs
    end
                  

    def check_input(str)
        case str
            when "help"
                self.help
            when "list servers" 
                self.list_servers
            when "list images" 
                self.list_images
            when "refresh servers"
                self.refresh_servers
            when "refresh images"
                self.refresh_images
            when "create server"
                self.create_server
            when "delete server"
                self.delete
            when "populate server"
                self.populate_server_records
            when "show server details"
                self.show_server_detail
            when "select server" 
                self.select_server_record
            when "show active server" 
                self.show_active_server_record
            when "exit", "quit" 
                puts "Bye Bye!"
                exit!
            else
                puts "wat?"
        end
    end

    def run
        while 1 do
            print "csclient> "
            input = gets.chomp
            self.check_input(input)
        end
    end
end
    
